# coding=utf-8
import json
import re
from lxml import etree

from core.item import Item
from core.m_logging import logger


def parse_ad_section(tree, keywords):
    # parse Best sellers
    list = []
    list_link = tree.xpath(
        '//div[@class="a-section octopus-pc-card ' + keywords + '"]/descendant::ul/li[@class="octopus-pc-item"]')
    for link in list_link:
        quick_look = link.xpath('descendant::span[@data-octopus-quick-look]/@data-octopus-quick-look')
        obj = json.loads(quick_look[0]) if len(quick_look) > 0 else None
        list.append(obj)

    return list

def parse_index(tree, metadata):
    nextPageUrl = tree.xpath('//a[@id="pagnNextLink"]/@href')

    # parse ad section, seems ad section are async call except best_seller
    bestSellerList = parse_ad_section(tree, "octopus-best-seller-card")
    mostWishList = parse_ad_section(tree, "octopus-most-wished-for-card")
    mostGiftedList = parse_ad_section(tree, "octopus-most-gifted-card")
    recommendedList = parse_ad_section(tree, "octopus-recommendation-card")
    hotNewReleasesList = parse_ad_section(tree, "octopus-new-release-card")
    topRatedList = parse_ad_section(tree, "octopus-top-rated-card")
    underPriceList = parse_ad_section(tree, "octopus-under-price-card")

    total_page = tree.xpath('//span[@class="pagnDisabled"]/text()')
    # parse main ansi list
    ansiList = []
    ansiList_link = tree.xpath('//div[@id="mainResults"]/ul/li[starts-with(@id, "result_")]')
    page_rank = 0
    for link in ansiList_link:
        page_rank += 1
        asin = link.xpath('@data-asin')
        product_summary_url = link.xpath('descendant::div[@class="a-section a-spacing-none a-inline-block s-position-relative"]/a[@class="a-link-normal a-text-normal"]/@href')
        review_url = link.xpath('descendant::div[@class="a-row a-spacing-none"]/a[@class="a-size-small a-link-normal a-text-normal"]/@href')
        product_name = link.xpath('descendant::a/descendant::h2/@data-attribute')
        product_image_url = link.xpath('descendant::a/img/@src')
        product_rating = link.xpath('descendant::i/span[@class="a-icon-alt"]/text()')
        customer_review = link.xpath(
            'descendant::div[@class="a-row a-spacing-top-micro"]/a[@class="a-size-small a-link-normal a-text-normal"]/text()')
        product_price = link.xpath('descendant::a/span[@class="a-offscreen"]/text()')
        shipping = link.xpath('descendant::div[@class="a-row a-spacing-none"]/span[@class="a-size-small"]/text()')
        stock = link.xpath(
            'descendant::div[@class="a-row a-spacing-none"]/span[@class="a-size-small a-color-price"]/text()')
        best_seller = link.xpath('descendant::div[@class="a-row sx-badge-region"]/descendant::a/@href')

        choice_type = link.xpath('descendant::span[text()="More Buying Choices"]/text()')
        choice_price = link.xpath('descendant::a[@class="a-size-small a-link-normal a-text-normal"]/span[@class="a-size-base a-color-base"]/text()')
        choice_count = link.xpath('descendant::a[@class="a-size-small a-link-normal a-text-normal"]/text()')

        choice_obj_dict = {"choice_type": f(choice_type),
                           "choice_count": f(choice_count),
                           "choice_price": f(choice_price)}

        ansi_obj_dict = {"asin": f(asin),
                         "product_summary_url": f(product_summary_url),
                         "review_url": f(review_url),
                         "product_name": f(product_name),
                         "product_image_url": f(product_image_url),
                         "product_rating": f(product_rating),
                         "customer_review": f(customer_review),
                         "product_price": f(product_price),
                         "shipping": f(shipping),
                         "stock": f(stock),
                         "choice": choice_obj_dict,
                         "best_seller": f(best_seller),
                         "page_rank": page_rank}
        ansiList.append(ansi_obj_dict)

    if len(ansiList) >= 1:
        item = Item({"success": True,
                     "status_code": metadata["status_code"],
                     "totalPage": f(total_page),
                     "nodeUrl": metadata["url"],
                     "nextPageUrl": nextPageUrl,
                     "ansiList": ansiList,
                     "bestSellerList": bestSellerList,
                     "mostWishList": mostWishList,
                     "mostGiftedList": mostGiftedList,
                     "recommendedList": recommendedList,
                     "hotNewReleasesList": hotNewReleasesList,
                     "topRatedList": topRatedList,
                     "underPriceList": underPriceList
                     })
        logger.info("parse index successful")
    else:
        # item = Item({"success": False, "text": metadata["text"]})
        item = Item({"success": False, "text": "omitted..."})
        logger.info("parse index failed")
    return item

def parse_paging(tree, metadata):
    # page_no = page(metadata['url'], r"page=(\d+)")

    nextPageUrl = tree.xpath('//ul[@class="a-pagination"]/li[@class="a-last"]/a/@href')
    ansiList = []
    ansiList_link = tree.xpath('//span[@data-component-type="s-search-results"]/div[@class="s-result-list sg-row"]/div[@data-asin]')
    page_rank = 0
    for link in ansiList_link:
        page_rank += 1
        asin = link.xpath('@data-asin')
        product_summary_url = link.xpath('descendant::span[@class="rush-component"]/a[@class="a-link-normal"]/@href')
        review_url = link.xpath('descendant::span[@aria-label]/a[@class="a-link-normal"]/@href')
        product_name = link.xpath('descendant::h5/descendant::span/text()')
        product_image_url = link.xpath('descendant::a/div/img/@src')
        product_rating = link.xpath('descendant::i/span[@class="a-icon-alt"]/text()')
        customer_review = link.xpath('descendant::a[@class="a-link-normal"]/span/text()')
        product_price = link.xpath('descendant::span[@class="a-price"]/span[@class="a-offscreen"]/text()')
        shipping = link.xpath('descendant::div[@class="a-section a-spacing-none a-spacing-top-micro"]/div/span[@class="a-size-small a-color-secondary"]/text()')
        stock = link.xpath('descendant::div[@class="a-row a-size-base a-color-secondary"]/span[@aria-label]/@aria-label')
        best_seller = None

        choice_type = link.xpath('descendant::div[@class="a-row a-size-base a-color-secondary"]/span[@class="a-size-base a-color-secondary"]/text()')
        choice_price = link.xpath('descendant::div[@class="a-row a-size-base a-color-secondary"]/span[@class="a-color-base"]/text()')
        choice_count = link.xpath('descendant::div[@class="a-row a-size-base a-color-secondary"]/a[@class="a-link-normal"]/text()')
        choice_obj_dict = {"choice_type": f(choice_type),
                           "choice_count": f(choice_count),
                           "choice_price": f(choice_price)}

        ansi_obj_dict = {"asin": f(asin),
                         "product_summary_url": f(product_summary_url),
                         "review_url": f(review_url),
                         "product_name": f(product_name),
                         "product_image_url": f(product_image_url),
                         "product_rating": f(product_rating),
                         "customer_review": f(customer_review),
                         "product_price": f(product_price),
                         "shipping": f(shipping),
                         "stock": f(stock),
                         "choice": choice_obj_dict,
                         "best_seller": f(best_seller),
                         "page_rank": page_rank}
        ansiList.append(ansi_obj_dict)

    if len(ansiList) >= 1:
        item = Item({"success": True, "status_code": metadata["status_code"], "nodeUrl": metadata["url"], "nextPageUrl": nextPageUrl, "ansiList": ansiList})
        logger.info("parse paging successful")
    else:
        # item = Item({"success": False, "text": metadata["text"]})
        item = Item({"success": False, "text": "omitted..."})
        logger.info("parse paging failed")
    return item


def robot_check(response):
    # html_doc = response.content.decode("utf-8")
    html_doc = response.content
    tree = etree.HTML(html_doc)
    robot = tree.xpath('//h4[text()="Enter the characters you see below"]/text()')
    if len(robot) > 0:
        logger.info("robot be caught!!!: %s" % robot)
        return True
    else:
        return False


def page(url, pattern):
    pattern = re.compile(pattern)
    matcher = re.search(pattern, url)
    if matcher and matcher.lastindex >= 1:
        page_no = matcher.group(1)
    else:
        page_no = "-1"
    return page_no


def f(lst):
    r = ""
    if isinstance(lst, list):
        if len(lst) > 0:
            for e in lst:
                r = e.strip()
                r = r.replace("\"", "`")
                # r = e.extract().decode('utf-8').strip()
                if r != "":
                    break
    return r